<?php

namespace common\components;

use Yii;
use yii\db\Expression;
class ActiveRecord extends \yii\db\ActiveRecord{

    const DELETED_YES   = 1;
    const DELETED_NO    = 0;
    const STATUS_YES    = 1;
    const STATUS_NO     = 0;

    public static $dropdownFields = [];
    /**
     * @todo 为了兼容mssql迁移到mysql过程中的字段问题
     * 字段映射(key 为mysql字段，value 为mssql字段)
     * ```php
     * [
     *     'uname'  => 'username',
     *     'pwd'    => 'password',
     * ]
     * ```
     * @var array
     */
    public static $fieldsMap = [];

    /**
     * 时间字段
     * 数据库存时间戳，而展示时使用的是datetime
     * @var unknown
     */
    public static $timeFields = ['_intm', '_uptm'];

    /**
     * 关联表属性，由子类决定哪些关联表字段需要排序
     * @var unknown
     */
    static $relationAttributes = [];

    /**
     * 获取当前所有的字段
     * {@inheritDoc}
     * @see \yii\db\ActiveRecord::attributes()
     */
    public function attributes(){
        $attributes = parent::attributes();
        if(static::$relationAttributes){
            foreach (static::$relationAttributes as $key => $attribute){
                if(is_numeric($key)){
                    $attributes[] = $attribute;
                }else{
                    $attributes[$key] = $attribute;
                }
            }
        }
        return $attributes;
    }

    /**
     * 插入数据到表中
     * @param unknown $columns
     * @param string $intm 为了兼容表中不包含_intm字段的表
     * @return \yii\db\string|number
     * @throws Exception if there is any DB error
     */
    public static function insertRow($columns, $intm = false){
        if($intm && !isset($columns['_intm'])){
            $columns['_intm'] = time();
        }
        $succ = static::getDb()->createCommand()->insert(static::tableName(), $columns)->execute();
        if($succ){
            $id = static::getDb()->getLastInsertID();
        }
        if($id){
            return $id;
        }else{
            return $succ;
        }
    }

    /**
     * 按主键更新数据
     * @param string $id, 如果是复合主键，则id以','分隔
     * @param unknown $columns
     * @return boolean
     * @throws Exception if there is any DB error
     */
    public static function updateByPk($id, array $columns){
        if(!$id || !$columns){
            return true;
        }
        $keys = static::primaryKey();
        $condition = [];
        if (count($keys) > 1) {
            $values = explode(',', $id);
            if (count($keys) === count($values)) {
                $condition = array_combine($keys, $values);
            }
        } elseif ($id !== null) {
            $condition[$keys[0]] = $id;
        }
        if(!$condition){
            return new \Exception('id为空或id和主键字段不对应');
        }
        return static::getDb()->createCommand()->update(static::tableName(), $columns, $condition)->execute();
    }

    /**
     * 按条件搜索总数
     * @param string | array  $condition
     * @return int or false;
     */
    public static function getTotal($condition, $params = [], $q = '*'){
        $total = static::find()->from(static::tableName())
            ->where($condition, $params)->count($q);
        return intval($total);
    }

    public static function getByPk($id){
        if(!$id){
            return [];
        }
        $keys = static::primaryKey();
        return static::find()->where([$keys[0] => $id])->asArray()->limit(1)->one();
    }

    public static function one($condition = [], $params = [], $columns = '*', $orderBy = [], $offset = null){
        return static::find()->select($columns)->asArray()
            ->where($condition, $params)->orderBy($orderBy)
            ->limit(1)->offset($offset)->one();
    }

    public static function all($condition = [], $params = [], $columns = '*', $orderBy = [], $limit = null, $offset = null){
        return static::find()->select($columns)->asArray()
            ->where($condition, $params)->orderBy($orderBy)
            ->limit($limit)->offset($offset)->all();
    }

    /**
     * 指定字段递增
     * @param unknown $id
     * @param string $field
     * @return number
     */
    public static function updateViews($id, $field = 'views'){
        try{
            if(!is_array($id)){
                $id = [$id];
            }
            $primaryKey = self::primaryKey()[0];
            return static::getDb()->createCommand()->update(static::tableName(), [$field => new Expression("{$field} + 1")], ['in',"{$primaryKey}", $id])->execute();
        }catch (\Exception $e){
            Yii::error($e->getMessage(),__METHOD__);
        }
    }

    public function timeCompare(&$query, $column, $prefix = ''){
        if(!$this->$column){
            return;
        }
        if (preg_match('/^(<>|>=|>|<=|<|=)/', $this->$column, $matches)) {
            $operator = $matches[1];
            $value = substr($this->$column, strlen($operator));
        } else {
            $operator = '=';
            $value = $this->$column;
        }
        if($value){
            if(!is_numeric($value)){
                $len    = strlen($value);
                $value  = strtotime($value);
                if($operator == '='){
                    if($len != 19){
                        $query->andFilterCompare($prefix.$column, '>='.$value)
                            ->andFilterCompare($prefix.$column, '<='.($value + 86400));
                    }else{
                        $query->andFilterCompare($prefix.$column, $operator.$value);
                    }
                }else{
                    $query->andFilterCompare($prefix.$column, $operator.$value);
                }
            }else{
                $query->filterWhere([$prefix.$column => $value]);
            }
        }
    }

    public function showError(){
        $attrbitesLable = $this->attributeLabels();
        $errors = $this->getErrors();
        $result = [];
        if($errors){
            foreach ($errors as $attribute => $error){
                $result[] = nl2br($attrbitesLable[$attribute].': '.implode('<br />', $error)).'<br />';
            }
        }
        $this->clearErrors();
        return implode('', $result);
    }
}
